package com.share.filter;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.share.result.JSONResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;

//登录检查
//@Component
@Slf4j
public class CheckLoginFilter implements GlobalFilter, Ordered {

    @Value("sa-token.token-name")
    private String tokenName;

//    @Autowired
    private LoginProperties loginProperties;

    private AntPathMatcher pathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取请求path
        String path = exchange.getRequest().getURI().getPath();
        if(isSkipCheckLogin(path)){
            log.info("请求Path ： {} 跳过登录检查");
            return chain.filter(exchange);
        }

        //检查请求头
        List<String> headers = exchange.getRequest().getHeaders().get(tokenName);
        if(headers == null || headers.size() == 0){
            log.info("请求头中没有satoken 提示去登录");
            return toLogin(exchange);
        }
        //校验Token
        String saToken = headers.get(0);
        StpUtil.setTokenValue(saToken);
        if(!StpUtil.isLogin()){
            log.info("请求头中没有satoken 提示去登录");
            return toLogin(exchange);
        }

        return chain.filter(exchange);
    }

    private boolean isSkipCheckLogin(String path){
        //匹配访问的path是否在放行的url当中
        for (String skipUrl : loginProperties.getUrls()) {
            if(pathMatcher.matchStart(path,skipUrl))
                return true;
        }
        return false;
    }

    //返回提示登录错误信息
    private  Mono<Void> toLogin(ServerWebExchange exchange){
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

        //错误信息封装
        JSONResult jsonResult = JSONResult.error("检查到未登录，请先登录");
        byte[] body = JSON.toJSONString(jsonResult).getBytes(StandardCharsets.UTF_8);
        //返回结果
        return response.writeWith(Mono.just(response.bufferFactory().wrap(body)));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
